package http

import (
	"fmt"
	"github.com/gofiber/fiber/v2"
	"github.com/pkg/errors"
	"github.com/spf13/viper"
	"go.uber.org/zap"
	"guns-excel/internal/pkg/log"
)

// 端口和模式
type Options struct {
	Host string
	Port int
	Mode string
}

// 服务
type Server struct {
	o        *Options
	app      string
	fiberApp *fiber.App
}

// 实例化选项
func NewOptions(v *viper.Viper) (*Options, error) {
	var (
		err error
		o   = new(Options)
	)
	if err = v.UnmarshalKey("http", o); err != nil {
		return nil, errors.Wrap(err, "初始化http 选项失败")
	}
	return o, nil
}

type InitControllers func(r *fiber.App)

func New(o *Options, app *fiber.App) (*Server, error) {
	var s = &Server{
		o:        o,
		fiberApp: app,
	}
	return s, nil
}

// 实例化路由，作为所有微服务的路由
func NewRouter(init InitControllers) *fiber.App {
	config := fiber.Config{}
	app := fiber.New(config)
	// 初始化所有的controller
	init(app)
	return app
}

func (s *Server) Start() error {
	// 获取端口
	addr := fmt.Sprintf("%s:%d", s.o.Host, s.o.Port)

	go func() {
		if err := s.fiberApp.Listen(addr); err != nil {
			log.Logger.Fatal("监听服务失败", zap.Error(err))
			return
		}
	}()
	return nil
}

// 停止服务
func (s *Server) Stop() error {
	if err := s.fiberApp.Shutdown(); err != nil {
		return errors.Wrap(err, "shutdown 服务失败")
	}
	return nil
}
